package zf.data.geom.plan
{
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import zf.data.geom.Beeline;
	import zf.data.geom.Formula;
	
	/**
	 * @private 未完成，且后面函数有问题
	 * 矩形。和Adobe官方 flash.geom.Rectangle 类似
	 * 扩展了些许碰撞检测
	 * @author mike.zhang
	 * @see flash.geom.Rectangle
	 * 
	 */
	public class Rect 
	{
		private var _x:Number;
		private var _y:Number;
		private var _width:Number;
		private var _height:Number;
		private var _radian:Number;
		
		private var _topLeft:Point;
		private var _topRight:Point;
		private var _bottomLeft:Point;
		private var _bottomRight:Point;
		
		/**
		 * 矩形 
		 * @param x 左上角x坐标
		 * @param y 左上角x坐标
		 * @param width 矩形宽度
		 * @param height 矩形长度
		 * @param radian 矩形宽所在的边和x轴所成角度的弧度，如果矩形旋转使得其他点成为图形所示的左上角点，此类中左上角点依然为旋转度为0时的左上角点
		 * 
		 */
		public function Rect(x:Number=0, y:Number=0, width:Number=0, height:Number=0,radian:Number=0)
		{
			_x=x;
			_y=y;
			_width=width;
			_height=height;
			_radian=radian;
			
			_topLeft=new Point(_x,_y);
		}

		/**
		 * 矩形左上角点，你可以通过设置该点来控制矩形大小和位置 
		 * @return 
		 * 
		 */
		public function get topLeft():Point
		{
			return _topLeft;
		}

		public function set topLeft(v:Point):void
		{
			
			if(_topLeft.equals(v)==false)
			{
				_topLeft = v;
				unAccount();
			}
		}

		/**
		 * 矩形右上角点 
		 * @return 
		 * 
		 */
		public function get topRight():Point
		{
			return _topRight;
		}

		/**
		 * 矩形左下角点
		 * @return 
		 * 
		 */
		public function get bottomLeft():Point
		{
			return _bottomLeft;
		}

		/**
		 * 矩形右下角点，你可以通过设置该点来控制矩形大小和位置  
		 * @return 
		 * 
		 */
		public function get bottomRight():Point
		{
			return _bottomRight;
		}

		public function set bottomRight(v:Point):void
		{
			if(_bottomRight.equals(v)==false)
			{
				_topLeft = v;
				unAccount();
			}
		}

		/**
		 * 矩形左上角x坐标 
		 * @return 
		 * 
		 */
		public function get x():Number
		{
			return _x;
		}

		public function set x(v:Number):void
		{
			_x = v;
		}

		/**
		 * 矩形左上角y坐标 
		 * @return 
		 * 
		 */
		public function get y():Number
		{
			return _y;
		}

		public function set y(v:Number):void
		{
			_y = v;
		}

		/**
		 * 矩形宽度 
		 * @return 
		 * 
		 */
		public function get width():Number
		{
			return _width;
		}

		public function set width(v:Number):void
		{
			if(_width!=v)
			{
				_width=v;
				account();
			}
		}

		/**
		 * 矩形高度 
		 * @return 
		 * 
		 */
		public function get height():Number
		{
			return _height;
		}

		public function set height(v:Number):void
		{
			if(_height!=v)
			{
				_height=v;
				account();
			}
		}
		
		/**
		 * 矩形width长度边与x轴所成的弧度 
		 * @return 
		 * 
		 */
		public function get radian():Number
		{
			return _radian;
		}

		public function set radian(v:Number):void
		{
			if(_radian!=v)
			{
				_radian=v;
				account();
			}
		} 
		
		/**
		 * 通过 Rectangle 创建一个Rect
		 * @param rect Adobe官方矩形类 Rectangle
		 * @return Rect
		 * 
		 */
		public static function RectangleToRect(rect:Rectangle):Rect
		{
			return new Rect(rect.x,rect.y,rect.width,rect.height,0);
		}
		
		public static function pointToRect(leftTop:Point=null,rightTop:Point=null,leftBottom:Point=null,rightBottom:Point=null):Rect
		{
			var t:uint=0;
			var arr:Array=new Array(leftTop,rightTop,rightBottom,leftBottom);
			//arguments
			for(var i:uint=0;i<4;i++)
			{
				if(arr[i]==null)
				{
					t++;
				}
			}
			var w:Number;
			var h:Number;
			if(t<1)
			{
				//判断矩形，一对对边平行且长度相等,对角线长度相等，并且左右两边点不相等
				var dx1:Number=leftTop.x-rightTop.x;
				var dx2:Number=leftBottom.x-rightBottom.x;
				var dy1:Number=leftTop.y-rightTop.y
				var dy2:Number=leftBottom.y-rightBottom.y;
				var bool:Boolean=dy1*dx2==dy2*dx1;
				if(bool==false)
				{
					return null;
				}
				bool=Formula.distanceSq(leftTop.x,leftTop.y,rightTop.x,rightTop.y)==Formula.distanceSq(leftBottom.x,leftBottom.y,rightBottom.x,rightBottom.y);
				if(bool==false)
				{
					return null;
				}
				bool=Formula.distanceSq(leftTop.x,leftTop.y,rightBottom.x,rightBottom.y)==Formula.distanceSq(rightTop.x,rightTop.y,leftBottom.x,leftBottom.y);
				if(bool==false)
				{
					return null;
				}
				if(leftTop.equals(leftBottom)==false)
				{
					w=Point.distance(leftTop,rightTop);
					h=Point.distance(leftTop,leftBottom);
					return new Rect(leftTop.x,leftTop.y,w,h,Math.atan(dy1/dx1));
				} 
				return null;
			}
			else if(t==1)
			{
				//已知3点
				var p:uint;
				var q:uint;
				var n:uint;
				var m:uint;
				for(i=0;i<4;i++)
				{
					q=(i+2)%4;
					if(arr[q]==null)
					{
						m=i;
						break;
					}
				}
				p=(m+3)%4;
				n=(m+1)%4;
				//var p0:Point=arr[p];
				//var p1:Point=arr[m];
				//var p2:Point=arr[n];
				//3点中2线垂直判断
				if((arr[p].y-arr[m].y)*(arr[m].y-arr[n].y)==(arr[p].x-arr[m].x)*(arr[n].x-arr[m].x))
				{
					var k:Number=(arr[p].y-arr[m].y)/(arr[p].x-arr[m].x);
					var bl1:Beeline=Beeline.KtoBeeline(k,arr[p]);
					var bl2:Beeline=Beeline.KtoBeeline(-1/k,arr[n]);
					arr[q]=bl1.hitBeeline(bl2);
					
					w=Point.distance(arr[0],arr[1]);
					h=Point.distance(arr[0],arr[4]);
					return new Rect(arr[0].x,arr[0].y,w,h,Math.atan((arr[0].y-arr[1].y)/(arr[0].x-arr[1].x)));
					
				}
				else
				{
					//不垂直
					return null;
				}
			}
			return null;
		}
		
		/**
		 * 已知左上点，宽，高，角度，求矩形其余点 
		 * @return 
		 * 
		 */
		private function account():void
		{
			var sa:Number=Math.sin(_radian);
			var ca:Number=Math.cos(_radian);
			_topRight=new Point(_x+ca*_width,_y+sa*_width);
			_bottomLeft=new Point(_x+sa*_height,_y+ca*_height);
			_bottomRight=new Point(_bottomLeft.x+ca*_width,_bottomLeft.y+sa*_width);
			
		}
		/**
		 * 已知四点，求矩形宽，高，角度 
		 * @return 
		 * 
		 */
		private function unAccount():void
		{
			//此处有问题
			_width=Point.distance(_topLeft,_topRight);
			_height=Point.distance(_topLeft,_bottomLeft);
			_radian=Math.atan((_topLeft.y-_topRight.y)/(_topLeft.x-_topRight.x));
		} 

	}
}